package util.util;


import java.io.File;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;
import java.util.Stack;

public class DevLogUtil {

    // 打印sql--计数用
    public static int logCount = 1;

    /**
     * 打印sql--读取文件成字符串
     *
     * @param file 文件
     * @param row  跳过的长度
     * @return
     */
    public static String getFileStr(File file, long row) {
        try {
            FileChannel inChannel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
            MappedByteBuffer inMappedBuf = inChannel.map(FileChannel.MapMode.READ_ONLY, row, inChannel.size() - row);
            byte[] dst = new byte[inMappedBuf.limit()];
            inMappedBuf.get(dst);
            return new String(dst);
        } catch (Exception e) {
            e.printStackTrace();
            return  "卧槽，读取文件错了。。。";
        }
    }

    /**
     * 打印sql--根据日志中的字符串，打印sql
     *
     * @param fileStr    日志信息
     * @param printParam 是否打印参数
     */
    public static String printLog(String fileStr, boolean printParam) {
        if (DevComUtil.isEmpty(fileStr)) {
            return null;
        }
        String[] logRow = fileStr.split("\n");
        StringBuffer sb = new StringBuffer();
        String sql1 = "";
        for (String rowStr : logRow) {
            if (rowStr.contains("[==>")) {
                String[] logRows = rowStr.split("\\[==>");
                String sql = logRows[1];
                if (sql.contains("?")) {
                    sql1 = sql.toUpperCase();
                } else {
                    // 红色输出时间
                    sb.append("\033[31;4m" + (logCount++) + ":" + logRows[0] + "\033[0m");
                    if (sql.contains("Parameters")) {
                        //  Parameters: 61d5f036e71d497ea25512f4b96403f0(String),  (String), R(String)]
                        String[] split = sql.replace(" Parameters: ", "").split(", ");
                        int length = split.length;
                        String[] params = new String[length];
                        for (int i = 0; i < length; i++) {
                            params[i] = "'" + split[i].split("\\(")[0] + "'";
                        }
                        String printSql = sql1.replace("?", "%s");

                        // 打印预编译的SQL和参数
                        if (printParam) {
                            print(sb, printSql, params);
                        }

                        String format;
                        try {
                            format = String.format(printSql, params);
                            String sqlStr = format.replace("Preparing: ", "").replace(" ]", "");
                            sb.append(formatSql(sqlStr));
                        } catch (Exception e) {
                            e.printStackTrace();
                            System.out.println("卧槽，此条sql打印有问题了，重新试一下啊。。。");
                        }

                    } else {
                        sb.append(sql);
                    }
                    sb.append("\n\n");
                }
            }
        }
        return sb.toString();
    }

    /**
     * 打印sql--根据日志中的字符串，打印sqlu
     *
     * @param fileStr    日志信息
     * @param printParam 是否打印参数
     */
    public static String printLog2(String fileStr, boolean printParam) {
        if (DevComUtil.isEmpty(fileStr)) {
            return null;
        }
        String[] logRow = fileStr.split("\n");
        StringBuffer sb = new StringBuffer();
        Stack<String> sql1 = new Stack<>();
        Stack<String> param1 = new Stack<>();

        Stack<String> title1 = new Stack<>();

        String splitChar = "==>";
        String notChar = "===>";

        for (int i = 0, n = logRow.length; i < n; i++) {
            String rowStr = logRow[i];
            if (rowStr.contains(splitChar) && !rowStr.contains(notChar)) {
                String[] logRows = rowStr.split(splitChar);
                if (logRows[1].contains("Preparing")) {
                    title1.push(logRow[i - 2]);
                    sql1.push(logRows[1].toUpperCase());
                } else if (logRows[1].contains("Parameters")) {

                    param1.push(logRows[1]);
                }
            }
        }

        Stack<String> sql = new Stack<>();
        Stack<String> param = new Stack<>();
        Stack<String> title = new Stack<>();

        if (!sql1.empty()) {
            sql.push(sql1.pop());
            param.push(param1.pop());
            title.push(title1.pop());
        }

        while (!sql.empty()) {
            String sqlText = sql.pop();

            sb.append("\033[31;4m" + (logCount++) + "  " + title.pop() + "\033[0m");
            if (sqlText.contains("?")) {
                String paramText = param.pop();
                //  Parameters: 61d5f036e71d497ea25512f4b96403f0(String),  (String), R(String)]
                String[] split = paramText.replace(" Parameters: ", "").split(", ");
                int length = split.length;
                String[] params = new String[length];
                for (int i = 0; i < length; i++) {
                    params[i] = "'" + split[i].split("\\(")[0] + "'";
                }
                String printSql = sqlText.replace("?", "%s");

                // 打印预编译的SQL和参数
                if (printParam) {
                    print(sb, printSql, params);
                }
                String format;
                try {
                    format = String.format(printSql, params);
                    String sqlStr = format.replace("PREPARING: ", "").replace(" ]", "");
                    sb.append(formatSql(sqlStr));
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("卧槽，此条sql打印有问题了，重新试一下啊。。。");
                }
            } else {
                param.pop();
                sb.append(formatSql(sqlText));
            }

            sb.append("\n");
            sb.append("\n");
        }
        if (!param.empty()) {
            System.out.println("卧槽，参数没有匹配好。。。。");
            while (!param.empty()) {
                System.out.println(param.pop());
            }

        }
        return sb.toString();
    }


    /**
     * 打印sql--整理SQL--换行
     *
     * @param sqlStr SQL字符串
     * @return 换行后的SQL字符串
     */
    public static String formatSql(String sqlStr) {

        if (sqlStr.startsWith("UPDATE") || sqlStr.startsWith("INSERT") ) {
            sqlStr = "\033[35;4m" + sqlStr + "\033[0m";
        } else if (sqlStr.startsWith("DELETE")) {
            sqlStr = "\033[34;4m" + sqlStr + "\033[0m";
        }

            return sqlStr.replace("SELECT", "\nSELECT")
                .replace(" FROM ", "\nFROM ")
                .replace(" WHERE ", "\nWHERE ")
                .replace(" UPDATE ", "\nUPDATE ")
                .replace(" DELETE ", "\nDELETE ")
                .replace(" INSERT ", "\nINSERT ")
                .replace(" GROUP ", "\nGROUP ")
                .replace(" ORDWE ", "\nORDWE ");
    }

    /**
     * 打印sql--打印预编译的SQL和参数
     *
     * @param printSql 预编译的SQL字符串
     * @param params   参数数组
     */
    public static void print(StringBuffer sb, String printSql, String[] params) {
        for (int i = 0; i < params.length; i++) {
            sb.append("###########params[" + i + "]:  " + params[i]);
            sb.append("\n");
        }
        sb.append("**********printSql:  " + printSql);
        sb.append("\n");
    }
}
